package org.glickr.api.places

import org.glickr.api.FlickrApiMethod
import groovy.util.slurpersupport.GPathResult
import org.glickr.FlickrServicePluginException
import org.glickr.FlickrServiceApiException
import org.glickr.FlickrPlace
import org.glickr.FlickrPlaceType

/* ----------------------------------------------------------------------------------------------------
REQUEST: flickr.places.getInfo
INFO: Get informations about a place.

AUTHENTICATION: This method does not require authentication.

ARGUMENTS:
api_key (Required): Your API application key.
place_id (Optional): A Flickr Places ID. (While optional, you must pass either a valid Places ID or a WOE ID.)
woe_id (Optional): A Where On Earth (WOE) ID. (While optional, you must pass either a valid Places ID or a WOE ID.)

EXAMPLE RESPONSE:
<place place_id="4hLQygSaBJ92" woeid="3534" latitude="45.512" longitude="-73.554" place_url="/Canada/Quebec/Montreal" place_type="locality" has_shapedata="1" timezone="America/Toronto">
  <locality place_id="4hLQygSaBJ92" woeid="3534" latitude="45.512" longitude="-73.554" place_url="/Canada/Quebec/Montreal">Montreal</locality>
  <county place_id="cFBi9x6bCJ8D5rba1g" woeid="29375198" latitude="45.551" longitude="-73.600" place_url="/cFBi9x6bCJ8D5rba1g">Montréal</county>
  <region place_id="CrZUvXebApjI0.72" woeid="2344924" latitude="53.890" longitude="-68.429" place_url="/Canada/Quebec">Quebec</region>
  <country place_id="EESRy8qbApgaeIkbsA" woeid="23424775" latitude="62.358" longitude="-96.582" place_url="/Canada">Canada</country>
  <shapedata created="1223513357" alpha="0.012359619140625" count_points="34778" count_edges="52" has_donuthole="1" is_donuthole="1">
    <polylines>
<polyline>
45.427627563477,-73.589645385742 45.428966522217,-73.587898254395, etc...
   </polyline>
    </polylines>
    <urls>
<shapefile>
   http://farm4.static.flickr.com/3228/shapefiles/3534_20081111_0a8afe03c5.tar.gz
   </shapefile>
    </urls>
  </shapedata>
</place>
---------------------------------------------------------------------------------------------------- */

class placesGetInfo implements FlickrApiMethod {
    //
    //  API METHOD
    //
    static final String apiMethod = 'flickr.places.getInfo'

    //
    //  VALIDATOR
    //
    Closure validatorClosure = { def model ->
        FlickrPlace place = model.place
        if (!place || (!place?.id && !place?.woeId)) { return [validated:false, message:"Required value 'FlickrPlace.id' or 'FlickrPlace.woeId' is missing"] }
        return [validated:true]
    }

    //
    //  PARAMS
    //
     Closure paramsClosure = { def model ->
        FlickrPlace place = model.place
        [place_id:place?.id]
    }

    //
    //  PROCESSOR
    //
    Closure processorClosure = { GPathResult response, def model = {} ->
        FlickrPlace place = model.place
        ArrayList<FlickrPlaceType> placeTypes = model.placeTypes

        place.id        = response.place.@place_id.toString()
        place.woeId     = response.place.@woeid.toLong()
        place.latitude  = response.place.@latitude.toBigDecimal()
        place.longitude = response.place.@longitude.toBigDecimal()
        place.type      = placeTypes.findAll{it.title.equals( response.place.@place_type.toString().toLowerCase() )}?.first()
        place.url       = response.place.@place_url.toString()
        place.timezone  = response.place.@timezone.toString()

        response.place.children().findAll{ it.name() in placeTypes.collect{it.title} }.each {
            if (it.@place_id.toString().equals(place.id)) {
                place.title = it.toString()
            } else {
                String tmpType = it.name().toString().toLowerCase()
                FlickrPlace tmpPlace = new FlickrPlace()

                tmpPlace.id        = it.@place_id.toString()
                tmpPlace.woeId     = it.@woeid.toLong()
                tmpPlace.title     = it.toString()
                tmpPlace.latitude  = it.@latitude.toBigDecimal()
                tmpPlace.longitude = it.@longitude.toBigDecimal()
                tmpPlace.type      = placeTypes.findAll{ it.title.equals(tmpType)}?.first()
                tmpPlace.url       = it.@place_url.toString()
                tmpPlace.timezone  = it.@timezone.toString()

                if (!(tmpPlace.id in place.places.collect{it.id})) {
                    place.places.add(tmpPlace)
                }
            }
        }
        return place
    }

    //
    //  ERROR CODES
    //
    Closure errorsClosure = { GPathResult response ->
        if (response.err.@code.toInteger() == 1) { return null }      // Required parameter missing
        if (response.err.@code.toInteger() == 2) { return null }      // Not a valid Places ID
        if (response.err.@code.toInteger() == 2) { return null }      // Place not found

        // recoverable errors
        if ([100,105,116].contains(response.err.@code.toInteger())) {
            return new FlickrServiceApiException(response)
        } else {
            return new FlickrServicePluginException(response)
        }
    }
}
